// Copyright (c) 2011 Blue Onion Software, All rights reserved
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web.UI.WebControls;
using BlueOnionSoftware.Bloget.Properties;

namespace BlueOnionSoftware.Bloget
{
    internal abstract class View : IDisposable
    {
        private bool _disposed;
        protected Bloget Bloget;
        private const int MaxTextBoxLength = 256;
        private const int MaxPasswordLength = 30;
        private readonly List<Label> _labels = new List<Label>();

        protected View(Bloget blogetArg)
        {
            Throw.IfNull(blogetArg, "blogetArg");
            Bloget = blogetArg;
        }

        protected abstract void ShowView();
        protected abstract string RootClassId();

        internal void Show()
        {
            var close = false;

            try
            {
                if (RootClassId() != null)
                {
                    Bloget.WriteLine("<div class=\"" + RootClassId() + "\">");
                    close = true;
                }

                ShowView();
            }

            finally
            {
                if (close)
                {
                    Bloget.WriteLine("</div>");
                }
            }
        }

        protected void Label(string text, string id)
        {
            Throw.IfNull(text, "text");
            Throw.IfNull(id, "id");

            var label = new Label();
            _labels.Add(label);
            label.Text = text + "&nbsp;";
            label.CssClass = RootClassId() + "-label";
            label.ID = "label" + id;
            label.AssociatedControlID = id;
            Bloget.Controls.Add(label);
        }

        protected static RequiredFieldValidator CreateRequiredFieldValidator(string id)
        {
            var rfv = new RequiredFieldValidator
            {
                ID = "rfv" + id, ControlToValidate = id,
                EnableClientScript = true,
                Text = Text.ButtonPadding(Resources.PasswordViewValidatorText)
            };
            return rfv;
        }

        protected void TextBoxField(TextBox textBox, string text, string toolTip)
        {
            if (textBox == null)
            {
                throw new ArgumentNullException("textBox");
            }
            if (text == null)
            {
                throw new ArgumentNullException("text");
            }
            if (toolTip == null)
            {
                throw new ArgumentNullException("toolTip");
            }
            textBox.Text = text;
            textBox.ToolTip = toolTip;
            textBox.MaxLength = MaxTextBoxLength;
            textBox.CssClass = RootClassId() + "-input";
            Bloget.Controls.Add(textBox);
        }

        protected void RequiredTextBoxField(TextBox textBox, string text, string toolTip)
        {
            if (textBox == null)
            {
                throw new ArgumentNullException("textBox");
            }
            TextBoxField(textBox, text, toolTip);
            Bloget.Controls.Add(CreateRequiredFieldValidator(textBox.ID));
        }

        protected void PasswordField(TextBox textBox)
        {
            if (textBox == null)
            {
                throw new ArgumentNullException("textBox");
            }
            TextBoxField(textBox, string.Empty, string.Empty);
            textBox.TextMode = TextBoxMode.Password;
            textBox.MaxLength = MaxPasswordLength;
        }

        protected void RequiredPasswordField(TextBox textBox)
        {
            if (textBox == null)
            {
                throw new ArgumentNullException("textBox");
            }
            PasswordField(textBox);
            Bloget.Controls.Add(CreateRequiredFieldValidator(textBox.ID));
        }

        protected void SubmitButton(Button button, string text)
        {
            if (button == null)
            {
                throw new ArgumentNullException("button");
            }
            if (string.IsNullOrEmpty(text))
            {
                throw (text == null)
                    ? new ArgumentNullException("button")
                    : new ArgumentException("button");
            }
            button.Text = Text.ButtonPadding(text);
            button.CssClass = RootClassId() + "-submit";
            Bloget.Controls.Add(button);
        }

        public void Dispose()
        {
            Dispose(true);
        }

        protected virtual void Dispose(bool disposing)
        {
            try
            {
                if (_disposed == false)
                {
                    _disposed = true;
                    if (disposing)
                    {
                        if (_labels != null)
                        {
                            foreach (var label in _labels.Where(label => label != null))
                            {
                                label.Dispose();
                            }
                        }
                    }
                }
            }

            finally
            {
                GC.SuppressFinalize(this);
            }
        }
    }
}